package order

import (
	"context"
	"fmt"
	"git.mycaigou.com/gfyx/common/tenant_db"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/common/constants"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/common/utils"
	"gorm.io/gorm"
	"time"
)

type orderRepository struct {
	tenant_db.TenantDB
}

func NewOrderRepository() GfyxOrderRepoIface {
	return &orderRepository{}
}

func (r *orderRepository) SaveOrder(ctx context.Context, data *GfyxOrderPo) (*GfyxOrderPo, error) {
	err := r.GetTenantDB(ctx).Table(GfyxOrderPo{}.TableName()).Create(data).Error
	if err != nil {
		return nil, err
	}
	return data, nil
}

func (r *orderRepository) UpdateOrderByCondition(ctx context.Context, condition, updates map[string]interface{}) error {
	db := r.GetTenantDB(ctx).Table(GfyxOrderPo{}.TableName())
	if len(condition) > 0 {
		if ids, ok := condition["ids"]; ok {
			db = db.Where("id in (?)", ids)
			delete(condition, "ids")
		}

		if createdTime, ok := condition["expired_time"]; ok {
			db = db.Where("created_on <= ?", createdTime)
			delete(condition, "expired_time")
		}

		if len(condition) > 0 {
			db = db.Where(condition)
		}
	}
	return db.Updates(updates).Error
}

func (r *orderRepository) QueryOrderById(ctx context.Context, id int64) (*GfyxOrderPo, error) {
	var po GfyxOrderPo
	err := r.GetTenantDB(ctx).Table(GfyxOrderPo{}.TableName()).Where("id =? and is_deleted = ?", id, constants.IsDeletedFalse).First(&po).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, nil
		}
		return nil, err
	}
	return &po, err

}

func (r *orderRepository) QueryOrderList(ctx context.Context, condition map[string]interface{}, pageInfo *utils.PageInfo) (int64, []*GfyxOrderPo, error) {
	var result []*GfyxOrderPo
	var count int64
	db := r.GetTenantDB(ctx).Table(GfyxOrderPo{}.TableName()) //.Where(condition)

	if condition != nil {
		if keyword, ok := condition["keyword"]; ok {
			db = db.Where("id = ? or digest like ?", keyword, fmt.Sprintf("%%%s%%", keyword))
			delete(condition, "keyword")
		}

		if paymentTimeMin, ok := condition["payment_time_min"]; ok {
			db = db.Where("payment_time >= ?", paymentTimeMin)
			delete(condition, "payment_time_min")
		}
		if paymentTimeMax, ok := condition["payment_time_max"]; ok {
			db = db.Where("payment_time <= ?", paymentTimeMax)
			delete(condition, "payment_time_max")
		}
		if finishStatus, ok := condition["status"]; ok {
			db = db.Where("status in (?)", finishStatus)
			delete(condition, "status")
		}
		if types, ok := condition["type"]; ok {
			db = db.Where("type in (?)", types)
			delete(condition, "type")
		}
		if paymentWay, ok := condition["payment_way"]; ok {
			db = db.Where("payment_way in (?)", paymentWay)
			delete(condition, "payment_way")
		}
		if len(condition) > 0 {
			db = db.Where(condition)
		}
	}

	err := db.Count(&count).Error
	if err != nil {
		return 0, nil, err
	}

	if pageInfo != nil && pageInfo.PageSize > 0 && pageInfo.Page > 0 {
		db = db.Offset((pageInfo.Page - 1) * pageInfo.PageSize).Limit(pageInfo.PageSize)
	}

	err = db.Order("id desc").Find(&result).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return 0, result, nil
		}
		return 0, nil, err
	}
	return count, result, nil
}

func (r *orderRepository) GetUsedExportNumByTime(ctx context.Context, sinceTime time.Time) (int32, error) {
	type total struct {
		Total int32
	}
	var myTotal total
	err := r.GetTenantDB(ctx).Table(GfyxOrderPo{}.TableName()).Select("sum(number) as total").
		Where("payment_time >=? and status =?", sinceTime, constants.OrderStatusPaid).Find(&myTotal).Error
	if err != nil {
		return 0, err
	}
	return myTotal.Total, nil
}
